Passed
Push — master ( 768538...392893 )
by Plamen
01:24
created

table.js ➔ initInstance   B

Complexity

Conditions 1
Paths 24

Size

Total Lines 117
Code Lines 93

Duplication

Lines 0
Ratio 0 %

Importance

Changes 13
Bugs 0 Features 0
Metric Value
cc 1
eloc 93
c 13
b 0
f 0
nc 24
nop 0
dl 0
loc 117
rs 7.229

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
var TableHelper = {
2
    Init: {
3
        SetColumnsHoverEffect: function (tContainer, tableId){
4
            var tHcells = tContainer.rows[0].cells;
5
            for(var i = 0; i < tHcells.length; i++){
6
                if(tHcells[i].firstChild.tagName === "A"){
7
                    tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableId + "'," + i + ");");
8
                    tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableId + "');");
9
                }
10
            }
11
        }
12
    },
13
    BuildRequest: {
14
        Sort: function (rq, strDesc){
15
            function sortBySpan(span, i){
16
                var order = span.innerHTML;
17
                if(order.length === 1){
18
                    rq.colNo = i;
19
                    rq.colOrd = order === strDesc ? "desc" : "asc";
20
                }
21
                return rq.colNo === i;
22
            }
23
24
            var thTags = document.getElementById(rq.tableId)
25
                    .getElementsByTagName("thead")[0]
26
                    .getElementsByTagName("th");
27
            var length = thTags.length;
28
            for(var i = 0; i < length; i++){
29
                var link = thTags[i].getElementsByTagName("a")[0];
30
                if(link){
31
                    var span = link.getElementsByTagName("span")[0];
32
                    if(span && sortBySpan(span, i)){
33
                        break;
34
                    }
35
                }
36
            }
37
        },
38
        Filter: function (rq){
39
            function getFilterFieldsByTableID(tableID){
40
                var fields = {filterBy: null, filter: null};
41
                var filterDiv = getFilterDivByTableIDOrNull(tableID);
42
                if(filterDiv !== null){
43
                    setFilterBy(fields, filterDiv);
44
                    setFilterValue(fields, filterDiv);
45
                }
46
                return fields;
47
            }
48
            function getFilterDivByTableIDOrNull(tableID){
49
                var res = null;
50
                if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
51
                    for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
52
                        if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
53
                            return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
54
                        }
55
                    }
56
57
                }
58
                return res;
59
            }
60
            function setFilterBy(fields, filterDiv){
61
                var slctObj = filterDiv.getElementsByTagName("select")[0];
62
                if(slctObj && slctObj.options[slctObj.selectedIndex].value !== "all"){
63
                    fields.filterBy = slctObj.options[slctObj.selectedIndex].value;
64
                }
65
            }
66
            function setFilterValue(fields, filterDiv){
67
                var textObj = filterDiv.getElementsByTagName("input")[0];
68
                if(textObj && textObj.value && textObj.value.length !== 0){
69
                    fields.filter = encodeURIComponent(textObj.value.trim());
70
                }
71
            }
72
73
            var r = getFilterFieldsByTableID(rq.tableId);
74
            if(r.filter !== null){
75
                rq.filter = r.filter;
76
            }
77
            if(r.filterBy !== null){
78
                rq.filterBy = r.filterBy;
79
            }
80
        }
81
    },
82
    
83
    ColumnHover: function(tableContainer, index){
84
        var rows = document.getElementById(tableContainer).rows;
85
        var upto = rows.length - 1;
86
        if(typeof index === "undefined"){
87
            ColumnHoverRelease(rows, upto);
88
        } else {
89
            for(var i = 0; i < upto; i++){
90
                rows[i].cells[index].setAttribute("lang", "col-hover");
91
            }
92
        }
93
        function ColumnHoverRelease(rows, upto){
94
            for(var i = 0; i < upto; i++){
95
                for(var j = 0; j < rows[i].cells.length; j++){
96
                    if(rows[i].cells[j].lang){
97
                        rows[i].cells[j].removeAttribute("lang");
98
                    }
99
                }
100
            }
101
        };
102
    },
103
    ProcessPaginationLinks: function(tfoot){
104
        var pLinks = tfoot.querySelectorAll(".paging a");
105
        if(pLinks.length > 0){
106
            for(var j = 0; j < pLinks.length; j++){
107
                pLinks[j].setAttribute("href", "javascript:void(0);");
108
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
109
            }
110
        }
111
    }
112
};
113
114
var TableHelperSetVisability = function(tableContainer, flag){
115
    var tbl = document.getElementById(tableContainer);
116
    if(flag === true){
117
        tbl.style.filter = "none";
118
        tbl.style.opacity = "1";
119
        tbl.style.cursor = "auto";
120
    }else if(flag === false){
121
        tbl.style.filter = "blur(1px)";
122
        tbl.style.opacity = "0.8";
123
        tbl.style.cursor = "wait";
124
    }else{
125
        console.error("table error in the flag value");
126
    }
127
};
128
129
var TableHelperGoPageGetNo = function(lnk, tableId){
130
    //check & serve pagination jump links
131
    var jumpDir = lnk.innerHTML.trim().substr(0, 1);
132
    if(jumpDir === "+" || jumpDir === "-"){
133
        var current = document.getElementById(tableId)
134
                        .querySelector("tfoot .paging .a").innerHTML;
135
        var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
136
        var jumpPage = (parseInt(current) + parseInt(jump));
137
        lnk.parentNode.setAttribute("data-page", jumpPage);
138
        lnk.style.transform = "none";
139
    }
140
    return lnk.parentNode.hasAttribute("data-page") ?
141
            lnk.parentNode.getAttribute("data-page") :
142
            lnk.innerHTML;
143
};
144
var TableHelperIePrior = function(v){
145
    var rv = false;
146
    if(window.navigator.appName === 'Microsoft Internet Explorer'){
147
        var ua = window.navigator.userAgent;
148
        var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
149
        if(re.exec(ua) !== null){
150
            rv = parseFloat(RegExp.$1);
151
        }
152
        rv = rv < v ? true : false;
153
    }
154
    return rv;
155
};
156
var TableHelperRequestToUrl = function(rq){
157
    var url = location.pathname + ".json" + location.search;
158
    if(typeof rq === "object"){
159
        var getUrlVarName = {
160
            colNo: "col", colOrd: "ord", filter: "filter",
161
            filterBy: "filter-by", pageNo: "pg", exportType: "export",
162
            tableId: "table-id"
163
        };
164
        var flagFirst = location.search.length < 1 ? true : false;
165
        for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
166
            var clue = flagFirst === true ? "?" : "&";
167
            url += clue + getUrlVarName[r] + "=" + rq[r];
168
            flagFirst = false;
169
        }
170
    }
171
    return url;
172
};
173
var TableHelperGetParent = function(obj, objType){
174
    while(obj && obj.tagName !== objType.toUpperCase()){
175
        obj = obj.parentNode;
176
    }
177
    return obj;
178
};
179
var TableHelperFilterGetTableId = function(field){
180
    if(field.tagName.toLowerCase() !== "select"){
181
        return field.getAttribute("data-table-id");
182
    }
183
    var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
184
    return '' === f.value ? null : f.getAttribute("data-table-id");
185
};
186
var TableHelperDraw_Section = function(tableContainer, dt, tSection){
187
    var section = tSection === "tfoot" ? "tfoot" : "tbody";
188
    var tSec = document.getElementById(tableContainer)
189
                .getElementsByTagName(section)[0];
190
    TableHelperDraw_SectionClear(tSec, TableHelperIePrior(9));
191
    for(var i = 0; i < dt.length; i++){
192
        var row = dt[i];
193
        var tRow = document.createElement("tr");
194
        TableHelperDraw_SectionRow(row, tRow);
195
        tSec.appendChild(tRow);
196
        if(section === "tfoot"){
197
            TableHelper.ProcessPaginationLinks(tSec);
198
        }
199
    }
200
};
201
var TableHelperDraw_SectionClear = function(tSection, iePrior9){
202
    if(iePrior9){
203
        if(tSection.firstChild){
204
            while(tSection.firstChild){
205
                tSection.removeChild(tSection.firstChild);
206
            }
207
        }
208
    }else{
209
        tSection.innerHTML = "";
210
    }
211
};
212
var TableHelperDraw_SectionRow = function(row, tRow){
213
    for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
214
        var tCell = document.createElement("td");
215
        if(typeof row[cell] === "string" || typeof row[cell] === "number"){
216
            tCell.innerHTML = row[cell];
217
        }else if(typeof row[cell] === "object"){
218
            TableHelperDraw_SectionRowCellFromObject(row, cell, tCell);
219
        }
220
        tRow.appendChild(tCell);
221
    }
222
};
223
var TableHelperDraw_SectionRowCellFromObject = function(row, cell, tCell){
224
    for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
225
        if(typeof row[cell][attr] === "string"){
226
            tCell.innerHTML = row[cell][attr];
227
        }else if(typeof row[cell][attr] === "object"){
228
            for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
229
                tCell.setAttribute(v, row[cell][attr][v]);
230
            }
231
        }
232
    }
233
};
234
235
//https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
236
var TableSingleton = (function(){
237
    // Instance stores a reference to the Singleton
238
    var instance;
239
    function initInstance(){
240
        // Singleton
241
        // Private methods and variables
242
        var tail = null;
243
        function Init(tableId){
244
            var tContainer = document.getElementById(tableId);
245
            if(!iePrior(9)){
246
                TableHelper.Init.SetColumnsHoverEffect(tContainer, tableId);
247
            }
248
            var tfoot = tContainer.getElementsByTagName("tfoot")[0];
249
            TableHelper.ProcessPaginationLinks(tfoot);
250
        }
251
        function BuildRequest(rq, crntTableId, strDesc){
252
            rq.tableId = crntTableId;
253
            TableHelper.BuildRequest.Sort(rq, strDesc);
254
            TableHelper.BuildRequest.Filter(rq);
255
        };
256
        function LoadData(tableContainer, rq){
257
            if(tail!==null){ tail.abort();}
258
            TableHelperSetVisability(tableContainer, false);
259
            var xmlhttp = window.XMLHttpRequest ? 
260
                            new XMLHttpRequest() : /* code for IE7+, Firefox, Chrome, Opera, Safari */
261
                            new window.ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
262
            xmlhttp.onreadystatechange = function(){
263
                if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
264
                    Draw(tableContainer, JSON.parse(xmlhttp.responseText));
265
                    TableHelperSetVisability(tableContainer, true);
266
                    instance.LoadEndCalback(tableContainer);
267
                }
268
            };
269
            xmlhttp.open("GET", RequestToUrl(rq), true);
270
            xmlhttp.send();
271
            tail = xmlhttp; //put at tail to can abort later any previous
272
        }
273
        function Draw(tableContainer, d){
274
            TableHelperDraw_Section(tableContainer, d.body);
275
            TableHelperDraw_Section(tableContainer, d.footer, "tfoot");
276
            if(instance.rq !== null){
277
                var hover = document.getElementById(instance.rq.tableId)
278
                            .getElementsByTagName("th")[instance.rq.colNo].lang;
279
                if(hover){
280
                    instance.ColumnHover(tableContainer, instance.rq.colNo);
281
                }
282
            }
283
        }
284
285
        var FilterGetTableId = TableHelperFilterGetTableId;
286
        var GoPageGetNo = TableHelperGoPageGetNo;
287
        var getParent = TableHelperGetParent;
288
        var iePrior = TableHelperIePrior;
289
        var RequestToUrl = TableHelperRequestToUrl;
290
291
        return {
292
            rq: null,
293
            strAsc: String.fromCharCode(9650), //&#9650;
294
            strDesc: String.fromCharCode(9660),//&#9660; 
295
            ReloadData: function(tableId){
296
                var request = {};
297
                BuildRequest(request, tableId, this.strDesc);
298
                LoadData(tableId, request);
299
            },
300
            Filter: function(field){
301
                var crntTableId = FilterGetTableId(field);
302
                if(crntTableId !== null){
303
                    var request = {};
304
                    var exRq = this.rq;
305
                    BuildRequest(request, crntTableId, this.strDesc);
306
                    if(exRq === null ||
307
                        request.filter !== exRq.filter ||
308
                        request.filterBy !== exRq.filterBy
309
                    ){
310
                        LoadData(crntTableId, request);
311
                    }
312
                }
313
            },
314
            GoPage: function(lnk){
315
                var request = {};
316
                var crntTableId = getParent(lnk, "table").getAttribute("id");
317
                BuildRequest(request, crntTableId, this.strDesc);
318
                request.pageNo = GoPageGetNo(lnk, crntTableId);
319
                LoadData(crntTableId, request);
320
                return false;
321
            },
322
            Export: function(lnk, eType){
323
                var request = {};
324
                var crntTableId = getParent(lnk, "table").getAttribute("id");
325
                BuildRequest(request, crntTableId, this.strDesc);
326
                request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ?
327
                                        eType : 
328
                                        "csv";
329
                window.open(RequestToUrl(request));
330
                return false;
331
            },
332
            Sort: function(colNo, lnk){
333
                var request = {};
334
                var crntTableId = getParent(lnk, "table").getAttribute("id");
335
                BuildRequest(request, crntTableId, this.strDesc);
336
                if(Math.round(colNo) === request.colNo){
337
                    request.colOrd = (request.colOrd === "asc" ? "desc" : "asc");
338
                }else{
339
                    request.colNo = Math.round(colNo);
340
                    request.colOrd = "asc";
341
                }
342
                LoadData(crntTableId, request);
343
                /* Clear and add new sort arrow */
344
                var headSpans = getParent(lnk, "thead").getElementsByTagName("span");
345
                var length = headSpans.length;
346
                for(var i = 0; i < length; i++){
347
                    headSpans[i].innerHTML = "";
348
                }
349
                lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? this.strDesc : this.strAsc);
350
            },
351
            ColumnHover: TableHelper.ColumnHover, //function(tableContainer, index)
352
            LoadEndCalback: function(){},/*Allows override: function(tableId){if(tableId){...}}*/
353
            init: Init
354
        };
355
    }
356
    return {
357
        //Get the Singleton instance if one exists, or create one if it doesn't
358
        getInstance: function(){
359
            if(!instance){
360
                instance = initInstance();
361
            }
362
            return instance;
363
        }
364
    };
365
})();
366
var table = TableSingleton.getInstance();
367